/*
 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
 *
 * Copyright (C) 2010 Oregon <http://www.oregoncore.com/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef OUTDOOR_PVP_NA_
#define OUTDOOR_PVP_NA_

#include "OutdoorPvP.h"

// TODO: "sometimes" set to neutral

enum OutdoorPvPNASpells
{
    NA_KILL_TOKEN_ALLIANCE = 33005,
    NA_KILL_TOKEN_HORDE = 33004,
    NA_CAPTURE_BUFF = 33795  // strength of the halaani
};

// kill credit for pks
const uint32 NA_CREDIT_MARKER = 24867;

const uint32 NA_GUARDS_MAX = 15;

const uint32 NA_BUFF_ZONE = 3518;

const uint32 NA_HALAA_GRAVEYARD = 993;

const uint32 NA_HALAA_GRAVEYARD_ZONE = 3518; // need to add zone id, not area id

const uint32 NA_RESPAWN_TIME = 3600000; // one hour to capture after defeating all guards

const uint32 NA_GUARD_CHECK_TIME = 500; // every half second

enum OutdoorPvPNAWorldStates
{
    NA_UI_HORDE_GUARDS_SHOW = 2503,
    NA_UI_ALLIANCE_GUARDS_SHOW = 2502,
    NA_UI_GUARDS_MAX = 2493,
    NA_UI_GUARDS_LEFT = 2491,

    NA_UI_TOWER_SLIDER_DISPLAY = 2495,
    NA_UI_TOWER_SLIDER_POS = 2494,
    NA_UI_TOWER_SLIDER_N = 2497,

    NA_MAP_WYVERN_NORTH_NEU_H = 2762,
    NA_MAP_WYVERN_NORTH_NEU_A = 2662,
    NA_MAP_WYVERN_NORTH_H = 2663,
    NA_MAP_WYVERN_NORTH_A = 2664,

    NA_MAP_WYVERN_SOUTH_NEU_H = 2760,
    NA_MAP_WYVERN_SOUTH_NEU_A = 2670,
    NA_MAP_WYVERN_SOUTH_H = 2668,
    NA_MAP_WYVERN_SOUTH_A = 2669,

    NA_MAP_WYVERN_WEST_NEU_H = 2761,
    NA_MAP_WYVERN_WEST_NEU_A = 2667,
    NA_MAP_WYVERN_WEST_H = 2665,
    NA_MAP_WYVERN_WEST_A = 2666,

    NA_MAP_WYVERN_EAST_NEU_H = 2763,
    NA_MAP_WYVERN_EAST_NEU_A = 2659,
    NA_MAP_WYVERN_EAST_H = 2660,
    NA_MAP_WYVERN_EAST_A = 2661,

    NA_MAP_HALAA_NEUTRAL = 2671,
    NA_MAP_HALAA_NEU_A = 2676,
    NA_MAP_HALAA_NEU_H = 2677,
    NA_MAP_HALAA_HORDE = 2672,
    NA_MAP_HALAA_ALLIANCE = 2673
};

const uint32 FLIGHT_NODES_NUM = 4;

// used to access the elements of Horde/AllyControlGOs
enum ControlGOTypes
{
    NA_ROOST_S = 0,
    NA_ROOST_W = 1,
    NA_ROOST_N = 2,
    NA_ROOST_E = 3,

    NA_BOMB_WAGON_S = 4,
    NA_BOMB_WAGON_W = 5,
    NA_BOMB_WAGON_N = 6,
    NA_BOMB_WAGON_E = 7,

    NA_DESTROYED_ROOST_S = 8,
    NA_DESTROYED_ROOST_W = 9,
    NA_DESTROYED_ROOST_N = 10,
    NA_DESTROYED_ROOST_E = 11,

    NA_CONTROL_GO_NUM = 12
};

const uint32 FlightPathStartNodes[FLIGHT_NODES_NUM] = {103,105,107,109};
const uint32 FlightPathEndNodes[FLIGHT_NODES_NUM] = {104,106,108,110};

enum FlightSpellsNA
{
    NA_SPELL_FLY_SOUTH = 32059,
    NA_SPELL_FLY_WEST = 32068,
    NA_SPELL_FLY_NORTH = 32075,
    NA_SPELL_FLY_EAST = 32081
};

// spawned when the alliance is attacking, horde is in control
const go_type HordeControlGOs[NA_CONTROL_GO_NUM] =
{
    {182267,530,-1815.8f,8036.51f,-26.2354f,-2.89725f,0.0f,0.0f,0.992546f,-0.121869f}, //ALLY_ROOST_SOUTH
    {182280,530,-1507.95f,8132.1f,-19.5585f,-1.3439f,0.0f,0.0f,0.622515f,-0.782608f}, //ALLY_ROOST_WEST
    {182281,530,-1384.52f,7779.33f,-11.1663f,-0.575959f,0.0f,0.0f,0.284015f,-0.95882f}, //ALLY_ROOST_NORTH
    {182282,530,-1650.11f,7732.56f,-15.4505f,-2.80998f,0.0f,0.0f,0.986286f,-0.165048f}, //ALLY_ROOST_EAST

    {182222,530,-1825.4022f,8039.2602f,-26.08f,-2.89725f,0.0f,0.0f,0.992546f,-0.121869f}, //HORDE_BOMB_WAGON_SOUTH
    {182272,530,-1515.37f,8136.91f,-20.42f,-1.3439f,0.0f,0.0f,0.622515f,-0.782608f}, //HORDE_BOMB_WAGON_WEST
    {182273,530,-1377.95f,7773.44f,-10.31f,-0.575959f,0.0f,0.0f,0.284015f,-0.95882f}, //HORDE_BOMB_WAGON_NORTH
    {182274,530,-1659.87f,7733.15f,-15.75f,-2.80998f,0.0f,0.0f,0.986286f,-0.165048f}, //HORDE_BOMB_WAGON_EAST

    {182266,530,-1815.8f,8036.51f,-26.2354f,-2.89725f,0.0f,0.0f,0.992546f,-0.121869f}, //DESTROYED_ALLY_ROOST_SOUTH
    {182275,530,-1507.95f,8132.1f,-19.5585f,-1.3439f,0.0f,0.0f,0.622515f,-0.782608f}, //DESTROYED_ALLY_ROOST_WEST
    {182276,530,-1384.52f,7779.33f,-11.1663f,-0.575959f,0.0f,0.0f,0.284015f,-0.95882f}, //DESTROYED_ALLY_ROOST_NORTH
    {182277,530,-1650.11f,7732.56f,-15.4505f,-2.80998f,0.0f,0.0f,0.986286f,-0.165048f}  //DESTROYED_ALLY_ROOST_EAST
};

// spawned when the horde is attacking, alliance is in control
const go_type AllianceControlGOs[NA_CONTROL_GO_NUM] =
{
    {182301,530,-1815.8f,8036.51f,-26.2354f,-2.89725f,0.0f,0.0f,0.992546f,-0.121869f}, //HORDE_ROOST_SOUTH
    {182302,530,-1507.95f,8132.1f,-19.5585f,-1.3439f,0.0f,0.0f,0.622515f,-0.782608f}, //HORDE_ROOST_WEST
    {182303,530,-1384.52f,7779.33f,-11.1663f,-0.575959f,0.0f,0.0f,0.284015f,-0.95882f}, //HORDE_ROOST_NORTH
    {182304,530,-1650.11f,7732.56f,-15.4505f,-2.80998f,0.0f,0.0f,0.986286f,-0.165048f}, //HORDE_ROOST_EAST

    {182305,530,-1825.4022f,8039.2602f,-26.08f,-2.89725f,0.0f,0.0f,0.992546f,-0.121869f}, //ALLY_BOMB_WAGON_SOUTH
    {182306,530,-1515.37f,8136.91f,-20.42f,-1.3439f,0.0f,0.0f,0.622515f,-0.782608f}, //ALLY_BOMB_WAGON_WEST
    {182307,530,-1377.95f,7773.44f,-10.31f,-0.575959f,0.0f,0.0f,0.284015f,-0.95882f}, //ALLY_BOMB_WAGON_NORTH
    {182308,530,-1659.87f,7733.15f,-15.75f,-2.80998f,0.0f,0.0f,0.986286f,-0.165048f}, //ALLY_BOMB_WAGON_EAST

    {182297,530,-1815.8f,8036.51f,-26.2354f,-2.89725f,0.0f,0.0f,0.992546f,-0.121869f}, //DESTROYED_HORDE_ROOST_SOUTH
    {182298,530,-1507.95f,8132.1f,-19.5585f,-1.3439f,0.0f,0.0f,0.622515f,-0.782608f}, //DESTROYED_HORDE_ROOST_WEST
    {182299,530,-1384.52f,7779.33f,-11.1663f,-0.575959f,0.0f,0.0f,0.284015f,-0.95882f}, //DESTROYED_HORDE_ROOST_NORTH
    {182300,530,-1650.11f,7732.56f,-15.4505f,-2.80998f,0.0f,0.0f,0.986286f,-0.165048f}  //DESTROYED_HORDE_ROOST_EAST
};

enum ControlNPCTypes
{
    NA_NPC_RESEARCHER = 0,
    NA_NPC_QUARTERMASTER,
    NA_NPC_BLADE_MERCHANT,
    NA_NPC_FOOD_MERCHANT,
    NA_NPC_AMMO,

    NA_NPC_GUARD_01,
    NA_NPC_GUARD_02,
    NA_NPC_GUARD_03,
    NA_NPC_GUARD_04,
    NA_NPC_GUARD_05,
    NA_NPC_GUARD_06,
    NA_NPC_GUARD_07,
    NA_NPC_GUARD_08,
    NA_NPC_GUARD_09,
    NA_NPC_GUARD_10,
    NA_NPC_GUARD_11,
    NA_NPC_GUARD_12,
    NA_NPC_GUARD_13,
    NA_NPC_GUARD_14,
    NA_NPC_GUARD_15,

    NA_CONTROL_NPC_NUM
};

const creature_type HordeControlNPCs[NA_CONTROL_NPC_NUM] =
{
    {18816,67,530,-1523.92f,7951.76f,-17.6942f,3.51172f},
    {18821,67,530,-1527.75f,7952.46f,-17.6948f,3.99317f},
    {21474,67,530,-1520.14f,7927.11f,-20.2527f,3.39389f},
    {21484,67,530,-1524.84f,7930.34f,-20.182f,3.6405f},
    {21483,67,530,-1570.01f,7993.8f,-22.4505f,5.02655f},
    {18192,67,530,-1654.06f,8000.46f,-26.59f,3.37f},
    {18192,67,530,-1487.18f,7899.1f,-19.53f,0.954f},
    {18192,67,530,-1480.88f,7908.79f,-19.19f,4.485f},
    {18192,67,530,-1540.56f,7995.44f,-20.45f,0.947f},
    {18192,67,530,-1546.95f,8000.85f,-20.72f,6.035f},
    {18192,67,530,-1595.31f,7860.53f,-21.51f,3.747f},
    {18192,67,530,-1642.31f,7995.59f,-25.8f,3.317f},
    {18192,67,530,-1545.46f,7995.35f,-20.63f,1.094f},
    {18192,67,530,-1487.58f,7907.99f,-19.27f,5.567f},
    {18192,67,530,-1651.54f,7988.56f,-26.5289f,2.98451f},
    {18192,67,530,-1602.46f,7866.43f,-22.1177f,4.74729f},
    {18192,67,530,-1591.22f,7875.29f,-22.3536f,4.34587f},
    {18192,67,530,-1550.6f,7944.45f,-21.63f,3.559f},
    {18192,67,530,-1545.57f,7935.83f,-21.13f,3.448f},
    {18192,67,530,-1550.86f,7937.56f,-21.7f,3.801f}
};

const creature_type AllianceControlNPCs[NA_CONTROL_NPC_NUM] =
{
    {18817,469,530,-1591.18f,8020.39f,-22.2042f,4.59022f},
    {18822,469,530,-1588.0f,8019.0f,-22.2042f,4.06662f},
    {21485,469,530,-1521.93f,7927.37f,-20.2299f,3.24631f},
    {21487,469,530,-1540.33f,7971.95f,-20.7186f,3.07178f},
    {21488,469,530,-1570.01f,7993.8f,-22.4505f,5.02655f},
    {18256,469,530,-1654.06f,8000.46f,-26.59f,3.37f},
    {18256,469,530,-1487.18f,7899.1f,-19.53f,0.954f},
    {18256,469,530,-1480.88f,7908.79f,-19.19f,4.485f},
    {18256,469,530,-1540.56f,7995.44f,-20.45f,0.947f},
    {18256,469,530,-1546.95f,8000.85f,-20.72f,6.035f},
    {18256,469,530,-1595.31f,7860.53f,-21.51f,3.747f},
    {18256,469,530,-1642.31f,7995.59f,-25.8f,3.317f},
    {18256,469,530,-1545.46f,7995.35f,-20.63f,1.094f},
    {18256,469,530,-1487.58f,7907.99f,-19.27f,5.567f},
    {18256,469,530,-1651.54f,7988.56f,-26.5289f,2.98451f},
    {18256,469,530,-1602.46f,7866.43f,-22.1177f,4.74729f},
    {18256,469,530,-1591.22f,7875.29f,-22.3536f,4.34587f},
    {18256,469,530,-1603.75f,8000.36f,-24.18f,4.516f},
    {18256,469,530,-1585.73f,7994.68f,-23.29f,4.439f},
    {18256,469,530,-1595.5f,7991.27f,-23.53f,4.738f}
};

enum WyvernStates
{
    WYVERN_NEU_HORDE = 1,
    WYVERN_NEU_ALLIANCE = 2,
    WYVERN_HORDE = 4,
    WYVERN_ALLIANCE = 8
};

enum HalaaStates
{
    HALAA_N = 1,
    HALAA_N_A = 2,
    HALAA_A = 4,
    HALAA_N_H = 8,
    HALAA_H = 16
};

class Unit;
class Creature;
class OutdoorPvPNA;

class OPvPCapturePointNA : public OPvPCapturePoint
{
    friend class OutdoorPvPNA;

    public:

        OPvPCapturePointNA(OutdoorPvP * pvp);

        bool Update(uint32 diff);

        void ChangeState();

        void SendChangePhase();

        void FillInitialWorldStates(WorldPacket & data);

        // used when player is activated/inactivated in the area
        bool HandlePlayerEnter(Player * plr);
        void HandlePlayerLeave(Player * plr);

        bool HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go);

        int32 HandleOpenGo(Player *plr, uint64 guid);

        uint32 GetAliveGuardsCount();

    protected:

        // called when a faction takes control
        void FactionTakeOver(uint32 team);

        void DeSpawnNPCs();
        void DeSpawnGOs();

        void SpawnNPCsForTeam(uint32 team);
        void SpawnGOsForTeam(uint32 team);

        void UpdateWyvernRoostWorldState(uint32 roost);
        void UpdateHalaaWorldState();

    private:

        bool m_capturable;

        uint32 m_GuardsAlive;

        uint32 m_ControllingFaction;

        uint32 m_WyvernStateNorth;
        uint32 m_WyvernStateSouth;
        uint32 m_WyvernStateEast;
        uint32 m_WyvernStateWest;

        uint32 m_HalaaState;

        uint32 m_RespawnTimer;

        uint32 m_GuardCheckTimer;
};

class OutdoorPvPNA : public OutdoorPvP
{
    friend class OPvPCapturePointNA;

    public:

        OutdoorPvPNA();

        bool SetupOutdoorPvP();

        void HandlePlayerEnterZone(Player *plr, uint32 zone);
        void HandlePlayerLeaveZone(Player *plr, uint32 zone);

        bool Update(uint32 diff);

        void FillInitialWorldStates(WorldPacket &data);

        void SendRemoveWorldStates(Player * plr);

        void HandleKillImpl(Player * plr, Unit * killed);

    private:

        OPvPCapturePointNA * m_obj;
};

#endif

